package com.crm.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crm.mapper.BusinessMapper;
import com.crm.mapper.ContractMapper;
import com.crm.pojo.common.*;
import com.crm.pojo.domain.Business;
import com.crm.pojo.domain.Contract;
import com.crm.pojo.dto.ActivityStatisticsDto;
import com.crm.pojo.dto.CluesStatisticsDto;
import com.crm.pojo.dto.ContractQueryDto;
import com.crm.pojo.dto.ContractStatisticsListDto;
import com.crm.pojo.vo.*;
import com.crm.service.BusinessService;
import com.crm.service.ContractService;
import com.crm.util.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: xaw
 * @CreateTime: 2025-09-04  12:27:30
 * @Description:
 * @Version: 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {

    private final ContractMapper contractMapper;

    private final BusinessMapper businessMapper;

    /**
     * 合同分页查询 Contract
     *
     * @param contractQueryDto
     * @return
     */
    @Override
    public PageResult pageQuery(ContractQueryDto contractQueryDto) {
        Page<ContractVo> page = new Page<>(contractQueryDto.getPageNum(), contractQueryDto.getPageSize());
        IPage<ContractVo> selectPage = contractMapper.pageQuery(page, contractQueryDto);
        log.info("合同Contract：pagetotal={},pageNum={},pageSize={},rows={}", selectPage.getTotal(), selectPage.getCurrent(), selectPage.getSize(), selectPage.getRecords());
        return PageInfo.getPageResult(selectPage);
    }

    @Override
    public PageResult getContractStatisticsList(ContractStatisticsListDto contractStatisticsListDto) {
        Page<ContractDetailVo> page = new Page<>(contractStatisticsListDto.getPageNum(), contractStatisticsListDto.getPageSize());
        Page<ContractDetailVo> detailVoPage = contractMapper.getContractDetailPage(page, contractStatisticsListDto);
        log.info("Statistics-合同详情：pagetotal={},pageNum={},pageSize={},rows={}", detailVoPage.getTotal(), detailVoPage.getCurrent(), detailVoPage.getSize(), detailVoPage.getRecords());
        return PageInfo.getPageResult(detailVoPage);
    }

    /**
     * 获取合同详情
     *
     * @param id
     * @return
     */
    @Override
    public ContractDetailVo getContractDetail(Integer id) {
        return contractMapper.getContractDetail(id);
    }

    @Override
    public PageResult getDeptStatisticsList(String beginCreateTime, String endCreateTime, BaseProperties baseProperties) {
        Page<DeptStatisticsVo> page = new Page<>(baseProperties.getPageNum(), baseProperties.getPageSize());
        Page<DeptStatisticsVo> deptStatisticsPage = contractMapper.getDeptStatisticsList(page, beginCreateTime, endCreateTime, baseProperties);
        log.info("Statistics-销售详情：pagetotal={},pageNum={},pageSize={},rows={}", deptStatisticsPage.getTotal(), deptStatisticsPage.getCurrent(), deptStatisticsPage.getSize(), deptStatisticsPage.getRecords());
        return PageInfo.getPageResult(deptStatisticsPage);
    }

    @Override
    public PageResult getCluesStatisticsList(CluesStatisticsDto cluesStatisticsDto) {
        Page<CluesStatisticsVo> page = new Page<>(cluesStatisticsDto.getPageNum(), cluesStatisticsDto.getPageSize());
        Page<CluesStatisticsVo> cluesStatisticsPage = contractMapper.getCluesStatisticsList(page, cluesStatisticsDto);
        return PageInfo.getPageResult(cluesStatisticsPage);
    }

    @Override
    public PageResult getActivityStatisticsList(ActivityStatisticsDto activityStatisticsDto) {
        Page<ActivityStatisticsVo> page = new Page<>(activityStatisticsDto.getPageNum(), activityStatisticsDto.getPageSize());
        Page<ActivityStatisticsVo> statisticsVoPage = contractMapper.getActivityStatisticsList(page, activityStatisticsDto);
        return PageInfo.getPageResult(statisticsVoPage);
    }
    // 前端传来创建时间的范围 beginCreateTime, endCreateTime

    /**
     * 获取新增用户数、用户总数
     *
     * @param beginCreateDate
     * @param endCreateDate
     * @return
     */
    @Override
    public StatisticsResult getContractStatistics(String beginCreateDate, String endCreateDate) {
        // 查询条件处理
        LocalDate beginDate = LocalDate.parse(beginCreateDate);
        LocalDate endDate = LocalDate.parse(endCreateDate);
        if (beginDate.isAfter(endDate)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        // 生成x轴日期列表List<LocalDate> xAxis
        List<LocalDate> xAxis = beginDate.datesUntil(endDate.plusDays(1)).collect(Collectors.toList());
        log.info("日期列表：{}", xAxis.size());

        // 转换成LocalDateTime
        LocalDateTime beginCreateTime = beginDate.atStartOfDay();
        LocalDateTime endCreateTime = endDate.plusDays(1).atStartOfDay();
        // 查询每天新增客户数
        List<Map<String, Object>> mapList = contractMapper.getContractStatistics(beginCreateTime, endCreateTime);
        // List类型转map
        Map<LocalDate, Integer> newMap = mapList.stream().collect(Collectors.toMap(
                row -> LocalDate.parse(row.get("date").toString()),
                row -> Integer.parseInt(row.get("count").toString())
        ));
        log.info("每日新增用户统计：{}", newMap);

        // 通过遍历日期列表给Result赋值
        List<Series> seriesList = new ArrayList<>();
        // 新增客户数
        List<Integer> newCdata = new ArrayList<>();
        // 客户总数
        int total = 0;
        ArrayList<Integer> totalCData = new ArrayList<>();
        // 遍历日期列表 xAxis，如果有对应的日期，则赋值
        for (LocalDate currDate : xAxis) {
            if (newMap.containsKey(currDate)) {
                newCdata.add(newMap.get(currDate));
            }
            newCdata.add(0);
            // 至当前日期客户总数
            int dayTotal = total + newMap.getOrDefault(currDate, 0);
            total += dayTotal;
            totalCData.add(dayTotal);
        }
        seriesList.add(new Series("新增客户数", newCdata));
        seriesList.add(new Series("客户总数", totalCData));
        return new StatisticsResult(xAxis, seriesList);
    }

    /**
     * 学科客户分布
     *
     * @param beginCreateDate
     * @param endCreateDate
     * @return
     */
    @Override
    public List<SubjectStatisticsVo> getSubjectStatistics(String beginCreateDate, String endCreateDate) {
        // 查询条件处理
        LocalDate beginDate = LocalDate.parse(beginCreateDate);
        LocalDate endDate = LocalDate.parse(endCreateDate);
        if (beginDate.isAfter(endDate)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        // 转换成LocalDateTime
        LocalDateTime beginCreateTime = beginDate.atStartOfDay();
        LocalDateTime endCreateTime = endDate.plusDays(1).atStartOfDay();
        List<SubjectStatisticsVo> statisticsVoList = contractMapper.getSubjectStatistics(beginCreateTime, endCreateTime);
        return statisticsVoList;
    }

    @Override
    public StatisticsResult getSalesStatistics(String beginCreateDate, String endCreateDate) {
        // 查询条件处理
        LocalDate beginDate = LocalDate.parse(beginCreateDate);
        LocalDate endDate = LocalDate.parse(endCreateDate);
        if (beginDate.isAfter(endDate)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        // 生成x轴日期列表List<LocalDate> xAxis
        List<LocalDate> xAxis = beginDate.datesUntil(endDate.plusDays(1)).collect(Collectors.toList());
        log.info("日期列表：{}", xAxis.size());

        // 转换成LocalDateTime
        LocalDateTime beginCreateTime = beginDate.atStartOfDay();
        LocalDateTime endCreateTime = endDate.plusDays(1).atStartOfDay();
        // 查询每天新增客户数
        List<Map<String, Object>> mapList = contractMapper.getSalesStatistics(beginCreateTime, endCreateTime);
        // List类型转map
        Map<LocalDate, Integer> newMap = mapList.stream().collect(Collectors.toMap(
                row -> LocalDate.parse((String) row.get("date")),
                row -> (Integer) row.get("count")
        ));
        log.info("map：{}", newMap);

        // 通过遍历日期列表给Result赋值
        List<Series> seriesList = new ArrayList<>();
        // 销售
        List<Integer> newCdata = new ArrayList<>();
        // 遍历日期列表 xAxis，如果有对应的日期，则赋值
        for (LocalDate currDate : xAxis) {
            if (newMap.containsKey(currDate)) {
                newCdata.add(newMap.get(currDate));
            }
            newCdata.add(0);
        }
        seriesList.add(new Series("销售统计", newCdata));
        return new StatisticsResult(xAxis, seriesList);
    }

    @Override
    public StatisticsResult getCluesStatistics(String beginCreateDate, String endCreateDate) {
        // 查询条件处理
        LocalDate beginDate = LocalDate.parse(beginCreateDate);
        LocalDate endDate = LocalDate.parse(endCreateDate);
        if (beginDate.isAfter(endDate)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        // 生成x轴日期列表List<LocalDate> xAxis
        List<LocalDate> xAxis = beginDate.datesUntil(endDate.plusDays(1)).collect(Collectors.toList());
        log.info("日期列表：{}", xAxis.size());

        // 转换成LocalDateTime
        LocalDateTime beginCreateTime = beginDate.atStartOfDay();
        LocalDateTime endCreateTime = endDate.plusDays(1).atStartOfDay();
        // 查询每天新增客户数
        List<Map<String, Object>> mapList = contractMapper.getCluesStatistics(beginCreateTime, endCreateTime);
        // List类型转map
        Map<LocalDate, Integer> newMap = mapList.stream().collect(Collectors.toMap(
                row -> LocalDate.parse(row.get("date").toString()),
                row -> Integer.parseInt(row.get("count").toString())
        ));
        log.info("每日新增线索统计：{}", newMap);

        // 通过遍历日期列表给Result赋值
        List<Series> seriesList = new ArrayList<>();
        // 新增线索数
        List<Integer> newCdata = new ArrayList<>();
        // 线索总数
        int total = 0;
        ArrayList<Integer> totalCData = new ArrayList<>();
        // 遍历日期列表 xAxis，如果有对应的日期，则赋值
        for (LocalDate currDate : xAxis) {
            if (newMap.containsKey(currDate)) {
                newCdata.add(newMap.get(currDate));
            }
            newCdata.add(0);
            // 至当前日期客户总数
            int dayTotal = total + newMap.getOrDefault(currDate, 0);
            total += dayTotal;
            totalCData.add(dayTotal);
        }
        seriesList.add(new Series("新增线索数量", newCdata));
        seriesList.add(new Series("线索总数量", totalCData));
        return new StatisticsResult(xAxis, seriesList);
    }
    //商机转合同
    @Transactional
    @Override
    public String changeContract(Integer id,ContractQueryDto dto) {
        Business business = businessMapper.selectById( id);
        if (business.getStatus() == 1){
            throw new RuntimeException(ErrorMessage.BUSINESS_ERROR_MESSAGE_TOCONTRACT_001);
        }
        Contract contract = new Contract();
        BeanUtils.copyProperties(business, contract);
        contract.setCreateBy(UserContext.getCurrentUser().getUserName());
        contract.setUpdateBy(UserContext.getCurrentUser().getUserName());
        contract.setCreateTime(LocalDateTime.now());
        contract.setUpdateTime(LocalDateTime.now());
        contract.setContractNo(dto.getContractNo());
        contract.setPhone(business.getPhone());
        contractMapper.add(contract); //新增合同
        businessMapper.endById(id);   //给商机标记为完成
        return "商机转合同成功";
    }

}
